home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
MenuHack
/
MenuHackSource.sit
/
jGNEEngineCodeResource.a
next >
Wrap
Text File
|
1996-05-09
|
6KB
|
217 lines
; $Workfile: jGNEEngineCodeResource.a $
; $Revision: 1.0 $
; This installs a 68k code block, hooks it into the GetNextEvent filter
; routines, and sets up a Gestalt mechanism that can get called. This allows
; applications to enter and remove filters safely
; © 1996 CE Software, Inc. All rights reserved.
; WHEN WHO WHAT
BLANKS ON
STRING ASIS
PRINT OFF
INCLUDE 'Traps.a'
INCLUDE 'ToolEqu.a'
INCLUDE 'QuickEqu.a'
INCLUDE 'SysEqu.a'
INCLUDE 'ATalkEqu.a'
INCLUDE 'PackMacs.a'
include 'ShutdownEqu.a'
include 'ScriptEqu.a'
include 'StandardFile.a'
include 'Processes.a'
PRINT ON
;
; Gestalt of type 'jGNE' will return the pointer to a routine that installs or
; removes an entry in the table.
;
; pascal void RegisterMe(short theAction, procptr theproc);
; 1, Register. Add an entry to the table with procptr, also keeping the processserialnumber
; 2, Dispose. Remove any entry with the current process, theproc is ignored
;
;
; We keep a table of entries within ourselves
;
TblProc equ 0 ;pointer to the routine to call, 0 means empty entry
TblRef equ TblProc+4 ;a data pointer we keep for the routine's use
TblPSN equ TblRef+4 ;Store the process serial number so we can check when the app crashes
TblSize equ TblPSN+8
TblMax equ 10 ;number of entries in the table
TblSpace equ TblMax*TblSize
jGNEEngineStuff main export
;
; This installs our hooks into the GNEFilter and registers us with Gestalt.
;
StartOfCode
move.l #'jGNE',D0
lea TheInstallProc,a1
_Gestalt
tst.w D0
beq.s @DoneHookup ;if no error, we're already installed somewhere else
lea StartOfCode,A0 ;We need to survive forever. Get the handle to ourselves.
_RecoverHandle
move.l A0,-(SP) ;put the handle on the stack twice
_Hlock ;and lock us down
_DetachResource ;make us hang around.
lea OldHook,A0 ;hook us into GNEFilter
move.l jGNEFilter,(A0)
lea myGNEFilter,A0
move.l A0,jGNEFilter
move.l #'jGNE',D0 ;register us so others can find us
LEA MyGestaltHandler,A0
_NewGestalt
@DoneHookup
rts
;
;
; The routine Gestalt will call to tell where my install routines are
;
MyGestaltHandler
link A6,#0
move.l 8(A6),A0 ;return the proper response
lea Myfunction,A1
move.l A1,(A0)
clr.w 16(A6)
unlk A6
move.l (SP)+,A0
adda.l #8,SP
jmp (A0)
;
; This is called by GetNextEvent, with the event mask in D0, and the pointer to the
; event record in A1. We'll look for our HotKey here.
;
gfThepsn equ -8
gfTheName equ gfThepsn-32
gfTheInfo equ gfTheName-processAppSpec-4
myGNEFilter
link A6,#gfTheInfo
movem.l D0-D5/A0-A3,-(SP)
move.l A1,A3
move.l D0,D4
lea TheItemsTbl,A2 ;get the pointer to the first pointer
moveq #TblMax-1,D5
@TheLoop tst.l TblProc(A2) ;skip any blanks
beq.s @NextLoop
move.l #processAppSpec+4,gfTheInfo(A6)
clr.l gfTheInfo+processAppSpec(A6)
lea gfTheName(A6),A0
move.l A0,gfTheInfo+processName(A6)
clr.w -(SP) ;see if we can get info on this process
pea TblPSN(A2)
pea gfTheInfo(A6)
_GetProcessInformation
tst.w (SP)+
beq.s @GotOne
clr.l TblProc(A2) ;bad entry, app must've crashed. Kill this entry
clr.l TblRef(A2)
clr.l TblPSN(A2)
clr.l TblPSN+4(A2)
bra.s @NextLoop
@GotOne
clr.w -(SP) ;OK, call this routine
move.l A3,-(SP)
move.l TblRef(A2),-(SP)
move.l TblProc(A2),A0
jsr (A0)
tst.w (SP)+ ;if returned true, he handled it
bne.s @CallTheLast
@NextLoop adda.l #TblSize,A2
dbra D5,@TheLoop
@CallTheLast
movem.l (SP)+,D0-D5/A0-A3
unlk A6
move.l OldHook, A0
jmp (A0)
;
; pascal void RegisterMe(short theAction, procptr theproc, long refcon);
; 1, Register. Add an entry to the table with procptr, also keeping the processserialnumber
; 2, Dispose. Remove any entry with the current process, theproc is ignored
;
myftheRefcon equ 8
myftheProc equ myftheRefcon+4
myftheAction equ myftheProc+4
myfThepsn equ -8
myfTheBool equ myfThepsn-2;
Myfunction link A6,#myfTheBool
movem.l D2-D5/A2,-(SP)
clr.l myfThepsn(A6) ;-8(A6) has our process serial number
clr.l myfThepsn+4(A6)
clr.w -(SP) ;see if we can get the next process
pea myfThepsn(A6)
_GetCurrentProcess
tst.w (SP)+
cmpi.w #1,myftheAction(A6) ;if it's register, do it
beq DoTheRegister
cmpi.w #2,myftheAction(A6) ;if it's dispose, do it
beq DoTheDispose
bra ReturnfromFunc
DoTheRegister
lea TheItemsTbl,A2 ;get the pointer to the first pointer
moveq #TblMax-1,D5
@TheLoop tst.l TblProc(A2) ;looking for an empty spot
bne.s @NextLoop
move.l myftheProc(A6),TblProc(A2) ;found one. Fill it out.
move.l myftheRefcon(A6),TblRef(A2)
move.l myfThepsn(A6),TblPSN(A2)
move.l myfThepsn+4(A6), TblPSN+4(A2);
bra ReturnFromFunc
@NextLoop adda.l #TblSize,A2
dbra D5,@TheLoop
bra ReturnFromFunc
DoTheDispose
lea TheItemsTbl,A2 ;get the pointer to the first pointer
moveq #TblMax-1,D5
@TheLoop
clr.w -(SP) ;call _SameProcess
pea myfThepsn(A6)
pea TblPSN(A2)
pea myfTheBool(A6)
clr.w myfTheBool(A6)
_SameProcess
tst.w (SP)+
tst.w myfTheBool(A6)
beq.s @NextLoop
Clr.l TblProc(A2) ;disposing, so get rid of it
clr.l TblRef(A2)
clr.l TblPSN(A2)
Clr.l TblPSN+4(A2)
@NextLoop adda.l #TblSize,A2
dbra D5,@TheLoop
;bra ReturnFromFunc
ReturnFromFunc
movem.l (SP)+,D2-D5/A2
unlk A6
move.l (SP)+,A0 ;clean up the stack
adda.l #10,SP
jmp (A0)
OldHook dc.l 0
TheInstallProc dc.l 0
TheItemsTbl dcb.b TblSpace,0
end